package com.nowcoder.community.c_service;

import com.nowcoder.community.a_entity.User;
import com.nowcoder.community.z_util.CommunityConstant;
import com.nowcoder.community.z_util.RedisKeyUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.core.RedisOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.SessionCallback;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * <p>——————————————————————————————————————————————-————
 * <p>   redis-关注、取关（2张表速查，涉及事务）
 * <p>——————————————————————————————————————————————-————
 */
@Service
public class FollowService implements CommunityConstant{
    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private UserService userService;

    //显示
    // 查询关注的实体的数量
    public long findFolloweeCount(int userId, int entityType){
        String k = RedisKeyUtil.getFolloweeKey(userId,entityType);
        return redisTemplate.opsForZSet().zCard(k);//zCard是size
    }

    // 查询实体的粉丝的数量
    public long findFollowerCount(int entityType, int entityId) {
        String followerKey = RedisKeyUtil.getFollowerKey(entityType, entityId);
        return redisTemplate.opsForZSet().zCard(followerKey);
    }
    // 查询当前用户是否已关注该实体
    public boolean hasFollowed(int userId, int entityType, int entityId) {
        String followeeKey = RedisKeyUtil.getFolloweeKey(userId, entityType);
        return redisTemplate.opsForZSet().score(followeeKey, entityId) != null;
    }


    //关注
    public void guanzhu(int userId,int entityType,int entityId){
        redisTemplate.execute(new SessionCallback() {
            @Override
            public Object execute(RedisOperations o) throws DataAccessException {
                //准备2张表的2个sql句
                String eeK = RedisKeyUtil.getFolloweeKey(userId,entityType);
                String erK = RedisKeyUtil.getFollowerKey(entityType,entityId);

                //开始入队
                o.multi();
                o.opsForZSet().add(eeK,entityId,System.currentTimeMillis());
                o.opsForZSet().add(erK,userId,System.currentTimeMillis());
                //执行
                return o.exec();
            }
        });
    }
    //取关（删）
    public void quguan(int userId,int entityType,int entityId){
        redisTemplate.execute(new SessionCallback() {
            @Override
            public Object execute(RedisOperations o) throws DataAccessException {
                //准备2张表的2个sql句
                String eeK = RedisKeyUtil.getFolloweeKey(userId,entityType);
                String erK = RedisKeyUtil.getFollowerKey(entityType,entityId);

                //开始入队
                o.multi();
                o.opsForZSet().remove(eeK,entityId,System.currentTimeMillis());
                o.opsForZSet().remove(erK,userId,System.currentTimeMillis());
                //执行
                return o.exec();
            }
        });
    }

    /**
     * <p>——————————————————————————————————————————————-————
     * <p>   return 该用户的关注列表 eelist
     * <p>——————————————————————————————————————————————-————
     */
    public List<Map<String, Object>> findFollowees(int userId, int offset, int limit) {
        //redis查 之后re
        String eeK = RedisKeyUtil.getFolloweeKey(userId,ENTITY_TYPE_USER);//这个定k是redis核心
        Set<Integer> tarIdList =  redisTemplate.opsForZSet().reverseRange(eeK,offset,offset+limit-1);//redis分页写法
        if(tarIdList==null)return null;

        List<Map<String, Object>> eelist = new ArrayList<>();
        for(int tarId: tarIdList){
            Map<String, Object> map = new HashMap<>();
            User user = userService.findUserByid(tarId);
            map.put("user",user);//都是user+本pojo

            Double score = redisTemplate.opsForZSet().score(eeK, tarId);
            map.put("followTime",new Date(score.longValue()));
            eelist.add(map);
        }
        return eelist;
    }

    /**
     * <p>——————————————————————————————————————————————-————
     * <p> 查询该用户的粉丝 return erlist
     * <p>——————————————————————————————————————————————-————
     */
    public List<Map<String, Object>> findFollowers(int userId, int offset, int limit) {
        String erK = RedisKeyUtil.getFollowerKey(ENTITY_TYPE_USER, userId);
        Set<Integer> idList = redisTemplate.opsForZSet().reverseRange(erK, offset, offset + limit - 1);
        if(idList==null)return null;

        List<Map<String, Object>> erlist = new ArrayList<>();
        for (Integer id : idList) {
            Map<String, Object> map = new HashMap<>();
            map.put("user",userService.findUserByid(id));

            map.put("followTime",new Date(redisTemplate.opsForZSet().score(erK,id).longValue()));
            erlist.add(map);//th不用getmap， 只需要getmap的String即可
        }
        return erlist;
    }
}
